#ifndef OPTFRAME_GRASPPRVP_HPP_
#define OPTFRAME_GRASPPRVP_HPP_

#include "../../OptFrame/Heuristic.hpp"

class GRASPPRVP: public Heuristic<RepPRVP, MemPRVP>
{
private:
	PRVPEvaluator& evaluator;
	BasicIteratedLocalSearchPRVP& h;
	BasicIteratedLocalSearchPRVP& h_exato;
	InitialSolution<RepPRVP> & initsol;
	unsigned int iterMax;

	PRVPProblemInstance& pPRVP;
	//lista pool
	LPool& lista;

public:

	using Heuristic<RepPRVP, MemPRVP>::exec; // prevents name hiding

	GRASPPRVP(PRVPProblemInstance& _pPRVP, PRVPEvaluator& _eval, InitialSolution<RepPRVP>& _initsol, BasicIteratedLocalSearchPRVP& _h,BasicIteratedLocalSearchPRVP& _h_exato, int _iterMax, LPool& _lista) :
		pPRVP(_pPRVP),evaluator(_eval), initsol(_initsol), h(_h), h_exato(_h_exato), iterMax(_iterMax), lista(_lista)
	{
	}

	virtual ~GRASPPRVP()
	{
	}

	virtual void exec(SolutionPRVP& s, double timelimit, double target_f)
	{
		EvaluationPRVP& e = evaluator.evaluate(s.getR());
		exec(s, e, timelimit, target_f);
		delete &e;
	}

	virtual void exec(SolutionPRVP& s, EvaluationPRVP& e, double timelimit, double target_f)
	{
		long tini = time(NULL);

		unsigned int iter = 0;

		long tnow = time(NULL);

		while (iter < iterMax && ((tnow - tini) < timelimit))
		{
			cout<< endl<< "GRASP iter " << iter <<endl;
			SolutionPRVP& s1 = initsol.generateSolution();
			EvaluationPRVP& e1 = evaluator.evaluate(s1.getR());

			h.exec(s1, e1, timelimit, target_f, lista);
			if (evaluator.betterThan(e1.evaluation(), e.evaluation()))
			{
				s = s1;
				e = e1;
				cout << "GRASP improvement " << iter << ": ";
				e.print();
			}

			delete &s1;
			delete &e1;

			tnow = time(NULL);
			iter++;
		}
		/*cout<<"antes: "<<endl;
		s.print();
		cout<<endl;*/

#ifdef EXATO

		SetPart set_partition(pPRVP, e, s);

		set_partition.geraMST(lista, s);

		//lista.verifica();

		set_partition.geraLP(lista);
		lista.print();
		set_partition.ambienteCPlex(lista, h_exato);

		s = set_partition.getSolution();
		e = set_partition.getEvaluation();
#endif

	}
};

#endif /*OPTFRAME_GRASPPRVP_HPP_*/
